/**
 * noty - jQuery Notification Plugin v1.2.1
 * Contributors: https://github.com/needim/noty/graphs/contributors
 *
 * Examples and Documentation - http://needim.github.com/noty/
 *
 * Licensed under the MIT licenses:
 * http://www.opensource.org/licenses/mit-license.php
 *
 **/
(function($) {
	$.noty = function(options, customContainer) {

		var base = {};
		var $noty = null;
		var isCustom = false;

		base.init = function(options) {
			base.options = $.extend({}, $.noty.defaultOptions, options);
			base.options.type = base.options.cssPrefix + base.options.type;
			base.options.id = base.options.type + '_' + new Date().getTime();
			base.options.layout = base.options.cssPrefix + 'layout_' + base.options.layout;

			if (base.options.custom.container) customContainer = base.options.custom.container;
			isCustom = ($.type(customContainer) === 'object') ? true : false;

			return base.addQueue();
		};

		// Push notification to queue
		base.addQueue = function() {
			var isGrowl = ($.inArray(base.options.layout, $.noty.growls) == -1) ? false : true;
			if (!isGrowl)(base.options.force) ? $.noty.queue.unshift({
				options: base.options
			}) : $.noty.queue.push({
				options: base.options
			});
			return base.render(isGrowl);
		};

		// Render the noty
		base.render = function(isGrowl) {

			// Layout spesific container settings
			var container = (isCustom) ? customContainer.addClass(base.options.theme + ' ' + base.options.layout + ' noty_custom_container') : $('body');
			if (isGrowl) {
				if ($('ul.noty_cont.' + base.options.layout).length == 0)
					container.prepend($('<ul/>').addClass('noty_cont ' + base.options.layout));
				container = $('ul.noty_cont.' + base.options.layout);
			} else {
				if ($.noty.available) {
					var fromQueue = $.noty.queue.shift(); // Get noty from queue
					if ($.type(fromQueue) === 'object') {
						$.noty.available = false;
						base.options = fromQueue.options;
					} else {
						$.noty.available = true; // Queue is over
						return base.options.id;
					}
				} else {
					return base.options.id;
				}
			}
			base.container = container;

			// Generating noty bar
			base.bar = $('<div class="noty_bar"/>').attr('id', base.options.id).addClass(base.options.theme + ' ' + base.options.layout + ' ' + base.options.type);
			$noty = base.bar;
			$noty.append(base.options.template).find('.noty_text').html(base.options.text);
			$noty.data('noty_options', base.options);

			// Close button display
			(base.options.closeButton) ? $noty.addClass('noty_closable').find('.noty_close').show(): $noty.find('.noty_close').remove();

			// Bind close event to button
			$noty.find('.noty_close').bind('click', function() {
				$noty.trigger('noty.close');
			});

			// If we have a button we must disable closeOnSelfClick and closeOnSelfOver option
			if (base.options.buttons) base.options.closeOnSelfClick = base.options.closeOnSelfOver = false;
			// Close on self click
			if (base.options.closeOnSelfClick) $noty.bind('click', function() {
				$noty.trigger('noty.close');
			}).css('cursor', 'pointer');
			// Close on self mouseover
			if (base.options.closeOnSelfOver) $noty.bind('mouseover', function() {
				$noty.trigger('noty.close');
			}).css('cursor', 'pointer');

			// Set buttons if available
			if (base.options.buttons) {
				$buttons = $('<div/>').addClass('noty_buttons');
				$noty.find('.noty_message').append($buttons);
				$.each(base.options.buttons, function(i, button) {
					bclass = (button.type) ? button.type : 'gray';
					$button = $('<button/>').addClass(bclass).html(button.text).appendTo($noty.find('.noty_buttons'))
						.bind('click', function() {
							if ($.isFunction(button.click)) {
								button.click.call($button, $noty);
							}
						});
				});
			}

			return base.show(isGrowl);
		};

		base.show = function(isGrowl) {

			// is Modal?
			if (base.options.modal) $('<div/>').addClass('noty_modal').addClass(base.options.theme).prependTo($('body')).fadeIn('fast');

			$noty.close = function() {
				return this.trigger('noty.close');
			};

			// Prepend noty to container
			(isGrowl) ? base.container.prepend($('<li/>').append($noty)): base.container.prepend($noty);

			// topCenter and center specific options
			if (base.options.layout == 'noty_layout_topCenter' || base.options.layout == 'noty_layout_center') {
				$.noty.reCenter($noty);
			}

			$noty.bind('noty.setText', function(event, text) {
				$noty.find('.noty_text').html(text);

				if (base.options.layout == 'noty_layout_topCenter' || base.options.layout == 'noty_layout_center') {
					$.noty.reCenter($noty);
				}
			});

			$noty.bind('noty.setType', function(event, type) {
				$noty.removeClass($noty.data('noty_options').type);

				type = $noty.data('noty_options').cssPrefix + type;

				$noty.data('noty_options').type = type;

				$noty.addClass(type);

				if (base.options.layout == 'noty_layout_topCenter' || base.options.layout == 'noty_layout_center') {
					$.noty.reCenter($noty);
				}
			});

			$noty.bind('noty.getId', function(event) {
				return $noty.data('noty_options').id;
			});

			// Bind close event
			$noty.one('noty.close', function(event) {
				var options = $noty.data('noty_options');
				if (options.onClose) {
					options.onClose();
				}

				// Modal Cleaning
				if (options.modal) $('.noty_modal').fadeOut('fast', function() {
					$(this).remove();
				});

				$noty.clearQueue().stop().animate(
						$noty.data('noty_options').animateClose,
						$noty.data('noty_options').speed,
						$noty.data('noty_options').easing,
						$noty.data('noty_options').onClosed)
					.promise().done(function() {

						// Layout spesific cleaning
						if ($.inArray($noty.data('noty_options').layout, $.noty.growls) > -1) {
							$noty.parent().remove();
						} else {
							$noty.remove();

							// queue render
							$.noty.available = true;
							base.render(false);
						}

					});
			});

			// Start the show
			if (base.options.onShow) {
				base.options.onShow();
			}
			$noty.animate(base.options.animateOpen, base.options.speed, base.options.easing, base.options.onShown);

			// If noty is have a timeout option
			if (base.options.timeout) $noty.delay(base.options.timeout).promise().done(function() {
				$noty.trigger('noty.close');
			});
			return base.options.id;
		};

		// Run initializer
		return base.init(options);
	};

	// API
	$.noty.get = function(id) {
		return $('#' + id);
	};
	$.noty.close = function(id) {
		//remove from queue if not already visible
		for (var i = 0; i < $.noty.queue.length;) {
			if ($.noty.queue[i].options.id == id)
				$.noty.queue.splice(id, 1);
			else
				i++;
		}
		//close if already visible
		$.noty.get(id).trigger('noty.close');
	};
	$.noty.setText = function(id, text) {
		$.noty.get(id).trigger('noty.setText', text);
	};
	$.noty.setType = function(id, type) {
		$.noty.get(id).trigger('noty.setType', type);
	};
	$.noty.closeAll = function() {
		$.noty.clearQueue();
		$('.noty_bar').trigger('noty.close');
	};
	$.noty.reCenter = function(noty) {
		noty.css({
			'left': ($(window).width() - noty.outerWidth()) / 2 + 'px'
		});
	};
	$.noty.clearQueue = function() {
		$.noty.queue = [];
	};

	var windowAlert = window.alert;
	$.noty.consumeAlert = function(options) {
		window.alert = function(text) {
			if (options) {
				options.text = text;
			} else {
				options = {
					text: text
				};
			}
			$.noty(options);
		};
	}
	$.noty.stopConsumeAlert = function() {
		window.alert = windowAlert;
	}

	$.noty.queue = [];
	$.noty.growls = ['noty_layout_topLeft', 'noty_layout_topRight', 'noty_layout_bottomLeft', 'noty_layout_bottomRight'];
	$.noty.available = true;
	$.noty.defaultOptions = {
		layout: 'top',
		theme: 'noty_theme_default',
		animateOpen: {
			height: 'toggle'
		},
		animateClose: {
			height: 'toggle'
		},
		easing: 'swing',
		text: '',
		type: 'alert',
		speed: 500,
		timeout: 5000,
		closeButton: false,
		closeOnSelfClick: true,
		closeOnSelfOver: false,
		force: false,
		onShow: false,
		onShown: false,
		onClose: false,
		onClosed: false,
		buttons: false,
		modal: false,
		template: '<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>',
		cssPrefix: 'noty_',
		custom: {
			container: null
		}
	};

	$.fn.noty = function(options) {
		return this.each(function() {
			(new $.noty(options, $(this)));
		});
	};

})(jQuery);

//Helper
function noty(options) {
	return jQuery.noty(options); // returns an id
}